﻿using Dyao.Book.Contract;
using Foundation.Core;

namespace Dyao.Book.Application
{
    /// <summary>
    /// 任务中心执行管理器
    /// </summary>
    /// <typeparam name="TResult">任务结果</typeparam>
    public class TaskCenterManager<TResult> : TaskCenterManager, ITransientDependency
    {
        public TaskCenterManager(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
        }

        /// <summary>
        /// 开始任务
        /// </summary>
        /// <returns></returns>
        public override Task StartAsync()
        {
            return UpdateCoreAsync(context =>
            {
                if (context.ExcuteBeginDatetime.HasValue)
                {
                    context.SetExecutedResult(null);
                }

                UpdateStartInfo(context);
            },
            TaskCenterRecordStatusEnum.Pending,
            isLogComplete: false,
            logLevel:TaskCenterRecordLogTypeEnum.Business,
            logMessage: "任务开始执行");
        }

        /// <summary>
        /// 设置执行结果
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        public Task SetResultAsync(TResult result)
        {
            return UpdateCoreAsync(context =>
            {
                var rsultString = Serialize(result);
                context.SetExecutedResult(rsultString);
            },
            isLogComplete: false,
            logLevel: TaskCenterRecordLogTypeEnum.System,
            logMessage: "更新Result");
        }

        /// <summary>
        /// 更新进度及结果
        /// </summary>
        /// <param name="action"></param>
        /// <param name="isAutoComplete">是否自动推断已完成</param>
        /// <returns></returns>
        public Task UpdateResultAsync(Action<TaskCenterRecordResultModel<TResult>> action, bool isAutoComplete = true)
        {
            return UpdateCoreAsync(async context =>
            {
                var str = await context.GetExecutedResultAsync();

                var model = LoadModel(context, new TaskCenterRecordResultModel<TResult>());
                model.ExcuteResult = Deserialize<TResult>(str);

                action(model);

                var resultString = Serialize(model.ExcuteResult);
                context.SetExecutedResult(resultString);
                StoreContext(context, model, isAutoComplete);
            },
            isLogComplete: isAutoComplete,
            logLevel: TaskCenterRecordLogTypeEnum.System,
            logMessage: "更新Result");
        }

        /// <summary>
        /// 执行成功
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public Task SuccessAsync(Action<TaskCenterRecordResultModel<TResult>> action)
        {
            return UpdateCoreAsync(async context =>
            {
                var str = await context.GetExecutedResultAsync();

                var model = LoadModel(context, new TaskCenterRecordResultModel<TResult>());
                model.ExcuteResult = Deserialize<TResult>(str);

                action(model);
                model.ExcutingProgress = 100;

                var resultString = Serialize(model.ExcuteResult);
                context.SetExecutedResult(resultString);

                StoreContext(context, model, true);
            },
            isLogComplete: true);
        }
    }
}
